package es.abredatos.energyes

import grails.converters.JSON
import java.text.SimpleDateFormat

class ChartController {
	
	// Injected by grails
	def chartService
	def dateService
	
	/**
	 * To add or remove a serie.
	 */
	def updateSerie = {
		def province, region
		def toRemove, energy
		Boolean allRegions = new Boolean(params.allRegions)
		Boolean add = new Boolean(params.add)
		log.debug("params:${params}")
		
		if(add) {
			log.debug("Añadiendo...")
			if(!allRegions) {
				region = Region.get(params.region)
				if(!region) {
					province = Province.get(params.province)
				}
			}
			
			if(!session.series) session.series = []
			
			if(params.energy != "-1") {
				energy = Energy.valueOf(params.energy)
			}
			session.series << [uuid:params.uuid, province:province, region:region, energy:energy]
		
			// updating dates
			['monthStart', 'monthEnd', 'yearStart', 'yearEnd'].each{
				session[it] = params.int(it)
			}
		} else {
			toRemove = session.series.find{it.uuid == params.uuid}
			
			log.debug("ToRemove:${toRemove}")
			
			if(toRemove) {
				session.series.remove(toRemove)
			}
		}
		
		chain(action:"timeline")
	}
	
	/**
	 * Renders homepage's timeline chart
	 */
	def timeline = {
		//session.series = []
		def monthStart = session.monthStart?:0
		def monthEnd = session.monthEnd?:11
		def yearStart = session.yearStart?:2010
		def yearEnd = session.yearEnd?:2010
		def series = session.series 
		
		def data = []
		def seriesNames = []
		
		if (series) {
			series.each { //Para cada serie en sesión
				log.debug("Region:${it.region}, province:${it.province}, energy:${it.energy}")
				data << getSerie(monthStart, monthEnd, yearStart, yearEnd, it.region, it.province, it.energy)
				seriesNames << getSerieName(it)
			}
		} else { //Una serie por defecto con todas las provincias y energías
			data << getDefaultSerie(monthStart, monthEnd, yearStart, yearEnd)
			seriesNames << "Toda España / Todas"
		}
		
		def numMonths = data[0].size()
		def tickInterval = getTickInterval(numMonths)
				
		[series: data as JSON, seriesNames: seriesNames as JSON, tickInterval: tickInterval]
	}
	
	def getSerieName(map) {
		def name = ""
		if (map.region) {
			name = map.region.name
		} else if (map.province) {
			name = map.province.name
		} else {
			name = "Toda España"
		}
		
		if (map.energy) {
			name += " / " + map.energy.toString().capitalize()
		} else {
			name += " / Todas"
		}
		name
	}
	
	def getSerie(monthStart, monthEnd, yearStart, yearEnd, region, province, energy) {
		def serie = []
		def data = chartService.returnProductionsToChart([yearStart, yearEnd],
			[monthStart, monthEnd], energy, region?Province.findAllByRegion(region):(province?:Province.list()))
		
		def numMonths = data.size()
		def axis = getAxisTicks(monthStart, yearStart, numMonths)
		
		numMonths.times {
			serie << [axis[it].replaceAll("'", ''), data[it]]
		}
		return serie
	}
	
	def getDefaultSerie(monthStart, monthEnd, yearStart, yearEnd) {
		def serie = []
		def data = chartService.returnProductionsToChart([yearStart, yearEnd],
			[monthStart, monthEnd], null, Province.list())

		def numMonths = data.size()
		def axis = getAxisTicks(monthStart, yearStart, numMonths)
		
		numMonths.times {
			serie << [axis[it].replaceAll("'", ''), data[it]]
		}
		return serie
	}
	
	/**	 
	 * Given a month/year beginning, returns properly formatted labels for the X axis
	 * eg: ['11/2009', '12/2010, '1/2011']
	 * 
	 * @param series
	 * @return
	 */
	private def getAxisTicks(monthStart, yearStart, numMonths) {
		def ticks = []
		def sdf = new SimpleDateFormat('yyyy-MM-dd', new Locale('es', 'ES'))
		numMonths.times {
			ticks << "'" + sdf.format(new GregorianCalendar(yearStart, monthStart + it, 1).time) + "'"
		}
		
		
		ticks
	}
	
	private def getTickInterval(numMonths) {
		def interval = numMonths / 10
		interval <= 1.5? "1 month" : "${(interval as Double).round()} months"
	}
	
	/**
	 * It renders the map chart, with 
	 */
	def map = {
		def icons = []
		def productionInfos, renewableImage, noRenewableImage
		def year = params.int('year') ?: dateService.findLastYearWithProductionItems()
		def rLat, rLng, nLat, nLng
		
		log.debug("Año considerado: ${year}")
		
		productionInfos = chartService.findAllProductionInfoByYear(year)
		
		productionInfos.each { productionInfo ->
			renewableImage = createIconLink(true, productionInfo.renewableIndex)
			noRenewableImage = createIconLink(false, productionInfo.noRenewableIndex)
			
			// Calculating the lat and lng for each marker
			rLat = productionInfo.region.lat
			rLng = productionInfo.region.lng
			nLat = productionInfo.region.lat
			nLng = productionInfo.region.lng - 0.7
			
			icons << [image:renewableImage, lat:rLat, lng:rLng, renewable:true, productionInfo:productionInfo]
			icons << [image:noRenewableImage, lat:nLat, lng:nLng, renewable:false, productionInfo:productionInfo]
		}
		
		icons.each { icon -> 
			log.debug("image:${icon.image}, lat:${icon.lat}, lng:${icon.lng}")
		}
		
		
		return [icons:icons]
	}
	
	private String createIconLink(boolean renewable, Integer index) {
		String dir = renewable ? 'renewable' : 'no_renewable'
		return resource(dir:"/images/${dir}", file:"${index}.png")
	}

}
